#include "GY_GraphicsRectWidthHeightItem.h"
#include <QPainterPath>
#include <QDebug>

GY_GraphicsRectWidthHeightItem::GY_GraphicsRectWidthHeightItem(const QString &guid, QGraphicsItem *parent)
    : GY_BasicsGraphicsObject(guid,this,parent)
{
    //图元类型
    GY_Object::setUserData(GY_ENUM::ClassType,QVariant("RectWidthHeight"));
    initializationPropertyInfo();
    updataPen();
    updataBrush();
    updatePath();
}

GY_GraphicsRectWidthHeightItem::GY_GraphicsRectWidthHeightItem(const QString &guid, const QPointF &position, const qreal &width, const qreal &height, QGraphicsItem *parent)
    : GY_BasicsGraphicsObject(guid,this,parent)
{
    //图元类型
    GY_Object::setUserData(GY_ENUM::ClassType,QVariant("RectWidthHeight"));
    initializationPropertyInfo();
    updataPen();
    updataBrush();
    m_PropertyInfoMap["Position"].propertyValue = this->mapFromScene(position);
    m_PropertyInfoMap["Width"].propertyValue = width;
    m_PropertyInfoMap["Height"].propertyValue =height;
    updatePath();
}

bool GY_GraphicsRectWidthHeightItem::updateLeftPoint(const QString &, const QVariant &value)
{
    if(!value.canConvert<QPointF>()){
        return false;
    }
    QPointF leftPoint = this->mapFromScene(value.toPointF());
    QPointF position = m_PropertyInfoMap["Position"].propertyValue.toPointF();
    position.setX(leftPoint.x());
    m_PropertyInfoMap["Position"].propertyValue = position;
    updatePath();
    return true;
}

bool GY_GraphicsRectWidthHeightItem::updateRightPoint(const QString &, const QVariant &value)
{
    if(!value.canConvert<QPointF>()){
        return false;
    }
    QPointF rightPoint = this->mapFromScene(value.toPointF());
    m_PropertyInfoMap["Width"].propertyValue = rightPoint.x()-m_PropertyInfoMap["Position"].propertyValue.toPointF().x();
    updatePath();
    return true;
}

bool GY_GraphicsRectWidthHeightItem::updateTopPoint(const QString &, const QVariant &value)
{
    if(!value.canConvert<QPointF>()){
        return false;
    }
    QPointF topPoint = this->mapFromScene(value.toPointF());
    m_PropertyInfoMap["Height"].propertyValue = topPoint.y()-m_PropertyInfoMap["Position"].propertyValue.toPointF().y();
    updatePath();
    return true;
}

bool GY_GraphicsRectWidthHeightItem::updateBottomPoint(const QString &, const QVariant &value)
{
    if(!value.canConvert<QPointF>()){
        return false;
    }
    QPointF bottomPoint = this->mapFromScene(value.toPointF());
    QPointF position = m_PropertyInfoMap["Position"].propertyValue.toPointF();
    position.setY(bottomPoint.y());
    m_PropertyInfoMap["Position"].propertyValue = position;
    updatePath();
    return true;
}

bool GY_GraphicsRectWidthHeightItem::updateWidthHeightPoint(const QString &, const QVariant &value)
{
    if(!value.canConvert<QPointF>()){
        return false;
    }
    QPointF widthHeightPoint = this->mapFromScene(value.toPointF());
    m_PropertyInfoMap["Width"].propertyValue = widthHeightPoint.x()-m_PropertyInfoMap["Position"].propertyValue.toPointF().x();
    m_PropertyInfoMap["Height"].propertyValue = widthHeightPoint.y()-m_PropertyInfoMap["Position"].propertyValue.toPointF().y();
    updatePath();
    return true;
}

bool GY_GraphicsRectWidthHeightItem::updatePositon(const QString &name, const QVariant &value)
{
    if(!value.canConvert<QPointF>()){
        return false;
    }
    QPointF position = this->mapFromScene(value.toPointF());
    m_PropertyInfoMap[name].propertyValue=position;
    updatePath();
    return true;
}

bool GY_GraphicsRectWidthHeightItem::updateWidth(const QString &name, const QVariant &value)
{
    if(!value.canConvert<qreal>()){
        return false;
    }
    m_PropertyInfoMap[name].propertyValue = value;
    updatePath();
    return true;
}

bool GY_GraphicsRectWidthHeightItem::updateHeight(const QString &name, const QVariant &value)
{
    if(!value.canConvert<qreal>()){
        return false;
    }
    m_PropertyInfoMap[name].propertyValue = value;
    updatePath();
    return true;
}

void GY_GraphicsRectWidthHeightItem::updatePath()
{
    QPointF position = m_PropertyInfoMap["Position"].propertyValue.toPointF();
    qreal width = m_PropertyInfoMap["Width"].propertyValue.toReal();
    qreal height = m_PropertyInfoMap["Height"].propertyValue.toReal();
    //!根据上面三个值画出所有编辑点
    m_PropertyInfoMap["widthHeightPoint"].propertyValue = QPointF(width+position.x(),height+position.y());
    m_PropertyInfoMap["leftPoint"].propertyValue = QPointF(position.x(),height/2+position.y());
    m_PropertyInfoMap["rightPoint"].propertyValue = QPointF(width+position.x(),height/2+position.y());
    m_PropertyInfoMap["topPoint"].propertyValue = QPointF(width/2+position.x(),height+position.y());
    m_PropertyInfoMap["bottomPoint"].propertyValue = QPointF(width/2+position.x(),position.y());
    //!设置编辑点
    QMap<QVariant,QPointF> editPoints = {{"widthHeightPoint",m_PropertyInfoMap["widthHeightPoint"].propertyValue.toPointF()},
                                         {"leftPoint",m_PropertyInfoMap["leftPoint"].propertyValue.toPointF()},
                                         {"rightPoint",m_PropertyInfoMap["rightPoint"].propertyValue.toPointF()},
                                         {"topPoint",m_PropertyInfoMap["topPoint"].propertyValue.toPointF()},
                                         {"bottomPoint",m_PropertyInfoMap["bottomPoint"].propertyValue.toPointF()}
                                        };
    this->setEditPointF(editPoints);
    //!设置中心点
    this->setCenterPointF(position);

    //!画出图形路径
    QPainterPath path = this->path();
    path.clear();
    path.moveTo(m_PropertyInfoMap["Position"].propertyValue.toPointF());
    path.lineTo(QPointF(m_PropertyInfoMap["widthHeightPoint"].propertyValue.toPointF().x(),m_PropertyInfoMap["Position"].propertyValue.toPointF().y()));
    path.lineTo(m_PropertyInfoMap["widthHeightPoint"].propertyValue.toPointF());
    path.lineTo(QPointF(m_PropertyInfoMap["Position"].propertyValue.toPointF().x(),m_PropertyInfoMap["widthHeightPoint"].propertyValue.toPointF().y()));
    path.closeSubpath();
    this->setPath(path);
}

void GY_GraphicsRectWidthHeightItem::initializationPropertyInfo()
{
    //位置
    GY_PropertyInfo positonPropertyInfo(this);
    positonPropertyInfo.propertyName="Position";
    positonPropertyInfo.propertyValue=QPointF(0,0);
    positonPropertyInfo.updateType = Update|MoveUpdate|PointOfRelative;
    positonPropertyInfo.propertyType = PointPropertyType;
    positonPropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updatePositon;
    m_PropertyInfoMap.insert(positonPropertyInfo.propertyName,positonPropertyInfo);
    m_PropertyInfoMap[positonPropertyInfo.propertyName].setConnect();

    GY_PropertyInfo Width(this);
    Width.propertyName = "Width";
    Width.propertyValue = qreal(200);
    Width.updateType = Update|OrdinaryAttributes;
    Width.propertyType = QrealPropertyType;
    Width.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updateWidth;
    m_PropertyInfoMap.insert("Width",Width);
    m_PropertyInfoMap["Width"].setConnect();

    GY_PropertyInfo Height(this);
    Height.propertyName = "Height";
    Height.propertyValue = qreal(100);
    Height.updateType = Update|OrdinaryAttributes;
    Height.propertyType = QrealPropertyType;
    Height.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updateHeight;
    m_PropertyInfoMap.insert("Height",Height);
    m_PropertyInfoMap["Height"].setConnect();

    GY_PropertyInfo leftPointPropertyInfo(this);
    leftPointPropertyInfo.propertyName="leftPoint";
    leftPointPropertyInfo.propertyValue=QPointF(0,50);
    leftPointPropertyInfo.updateType = NotUpdate;
    leftPointPropertyInfo.propertyType = PointPropertyType;
    leftPointPropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updateLeftPoint;
    m_PropertyInfoMap.insert("leftPoint",leftPointPropertyInfo);
    m_PropertyInfoMap[leftPointPropertyInfo.propertyName].setConnect();

    GY_PropertyInfo rightPointPropertyInfo(this);
    rightPointPropertyInfo.propertyName="rightPoint";
    rightPointPropertyInfo.propertyValue=QPointF(200,50);
    rightPointPropertyInfo.updateType = NotUpdate;
    rightPointPropertyInfo.propertyType = PointPropertyType;
    rightPointPropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updateRightPoint;
    m_PropertyInfoMap.insert("rightPoint",rightPointPropertyInfo);
    m_PropertyInfoMap[ rightPointPropertyInfo.propertyName].setConnect();

    GY_PropertyInfo topPointPropertyInfo(this);
    topPointPropertyInfo.propertyName="topPoint";
    topPointPropertyInfo.propertyValue=QPointF(100,100);
    topPointPropertyInfo.updateType = NotUpdate;
    topPointPropertyInfo.propertyType = PointPropertyType;
    topPointPropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updateTopPoint;
    m_PropertyInfoMap.insert("topPoint",topPointPropertyInfo);
    m_PropertyInfoMap[topPointPropertyInfo.propertyName].setConnect();

    GY_PropertyInfo bottomPointPropertyInfo(this);
    bottomPointPropertyInfo.propertyName="bottomPoint";
    bottomPointPropertyInfo.propertyValue=QPointF(100,0);
    bottomPointPropertyInfo.updateType = NotUpdate;
    bottomPointPropertyInfo.propertyType = PointPropertyType;
    bottomPointPropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updateBottomPoint;
    m_PropertyInfoMap.insert("bottomPoint",bottomPointPropertyInfo);
    m_PropertyInfoMap[bottomPointPropertyInfo.propertyName].setConnect();

    GY_PropertyInfo widthHeightPointPropertyInfo(this);
    widthHeightPointPropertyInfo.propertyName="widthHeightPoint";
    widthHeightPointPropertyInfo.propertyValue=QPointF(200,100);
    widthHeightPointPropertyInfo.updateType = NotUpdate;
    widthHeightPointPropertyInfo.propertyType = PointPropertyType;
    widthHeightPointPropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updateWidthHeightPoint;
    m_PropertyInfoMap.insert("widthHeightPoint",widthHeightPointPropertyInfo);
    m_PropertyInfoMap[widthHeightPointPropertyInfo.propertyName].setConnect();

    GY_PropertyInfo ObjectName(this);
    ObjectName.propertyName = "ObjectName";
    ObjectName.propertyValue = QString();
    ObjectName.updateType = Update|OrdinaryAttributes;
    ObjectName.propertyType = QStringPropertyType;
    ObjectName.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updateObjectName;
    m_PropertyInfoMap.insert("ObjectName",ObjectName);
    m_PropertyInfoMap[ObjectName.propertyName].setConnect();

    GY_PropertyInfo IsOutLined(this);
    IsOutLined.propertyName = "IsOutlined";
    IsOutLined.propertyValue = true;
    IsOutLined.updateType = Update|OrdinaryAttributes;
    IsOutLined.propertyType = BoolPropertyType;
    IsOutLined.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updateIsOutLined;
    m_PropertyInfoMap.insert("IsOutlined",IsOutLined);
    m_PropertyInfoMap[IsOutLined.propertyName].setConnect();

    GY_PropertyInfo IsFilled(this);
    IsFilled.propertyName = "IsFilled";
    IsFilled.propertyValue = true;
    IsFilled.updateType = Update|OrdinaryAttributes;
    IsFilled.propertyType = BoolPropertyType;
    IsFilled.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updateIsFilled;
    m_PropertyInfoMap.insert("IsFilled",IsFilled);
    m_PropertyInfoMap[IsFilled.propertyName].setConnect();

    GY_PropertyInfo IsAntialiased(this);
    IsAntialiased.propertyName = "IsAntialiased";
    IsAntialiased.propertyValue = true;
    IsAntialiased.updateType = Update|OrdinaryAttributes;
    IsAntialiased.propertyType = BoolPropertyType;
    IsAntialiased.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updateIsAntialiased;
    m_PropertyInfoMap.insert("IsAntialiased",IsAntialiased);
    m_PropertyInfoMap[IsAntialiased.propertyName].setConnect();

    GY_PropertyInfo FillAttributes(this);
    FillAttributes.propertyName = "FillAttributes";
    FillAttributes.propertyValue = false;
    FillAttributes.updateType = Update|OrdinaryAttributes;
    FillAttributes.propertyType = BoolPropertyType;
    FillAttributes.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updateFillAttributes;
    m_PropertyInfoMap.insert("FillAttributes",FillAttributes);
    m_PropertyInfoMap[FillAttributes.propertyName].setConnect();

    GY_PropertyInfo FillGradient(this);
    FillGradient.propertyName = "FillGradient";
    FillGradient.propertyValue = QVariant();
    FillGradient.updateType = Update|OrdinaryAttributes;
    FillGradient.propertyType = FillGradientPropertyType;
    FillGradient.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updateFillGradient;
    m_PropertyInfoMap.insert("FillGradient",FillGradient);
    m_PropertyInfoMap[FillGradient.propertyName].setConnect();

    GY_PropertyInfo FillColor(this);
    FillColor.propertyName = "FillColor";
    FillColor.propertyValue = QColor();
    FillColor.updateType = Update|OrdinaryAttributes;
    FillColor.propertyType = ColorPropertyType;
    FillColor.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updateFillColor;
    m_PropertyInfoMap.insert("FillColor",FillColor);
    m_PropertyInfoMap[FillColor.propertyName].setConnect();

    GY_PropertyInfo FillStyle(this);
    FillStyle.propertyName = "FillStyle";
    FillStyle.propertyValue = true;
    FillStyle.updateType = Update|OrdinaryAttributes;
    FillStyle.propertyType = BoolPropertyType;
    FillStyle.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updateFillStyle;
    m_PropertyInfoMap.insert("FillStyle",FillStyle);
    m_PropertyInfoMap[FillStyle.propertyName].setConnect();

    GY_PropertyInfo FillOpacity(this);
    FillOpacity.propertyName = "FillOpacity";
    FillOpacity.propertyValue = 1;
    FillOpacity.updateType = Update|OrdinaryAttributes;
    FillOpacity.propertyType = QrealPropertyType;
    FillOpacity.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updateFillOpacity;
    m_PropertyInfoMap.insert("FillOpacity",FillOpacity);
    m_PropertyInfoMap[FillOpacity.propertyName].setConnect();

    //Pattern填充图案数据
    QVector<QPoint> points;
    points << QPoint(0,1)<< QPoint(2,1)<< QPoint(3,1) << QPoint(5,1)<< QPoint(5,15) << QPoint(14,8);
    GY_PropertyInfo Pattern(this);
    Pattern.propertyName = "Pattern";
    Pattern.propertyValue = QVariant();
    Pattern.updateType = Update|OrdinaryAttributes;
    Pattern.propertyType = PatternPropertyType;
    Pattern.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updatePattern;
    m_PropertyInfoMap.insert("Pattern",Pattern);
    m_PropertyInfoMap[Pattern.propertyName].setConnect();

    GY_PropertyInfo PenColor(this);
    PenColor.propertyName = "PenColor";
    PenColor.propertyValue = QColor();
    PenColor.updateType = Update|OrdinaryAttributes;
    PenColor.propertyType = ColorPropertyType;
    PenColor.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updatePenColor;
    m_PropertyInfoMap.insert("PenColor",PenColor);
    m_PropertyInfoMap[PenColor.propertyName].setConnect();

    GY_PropertyInfo PenAttributes(this);
    PenAttributes.propertyName = "PenAttributes";
    PenAttributes.propertyValue = false;
    PenAttributes.updateType = Update|OrdinaryAttributes;
    PenAttributes.propertyType = BoolPropertyType;
    PenAttributes.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updatePenAttributes;
    m_PropertyInfoMap.insert("PenAttributes",PenAttributes);
    m_PropertyInfoMap[PenAttributes.propertyName].setConnect();

    GY_PropertyInfo PenOpacity(this);
    PenOpacity.propertyName = "PenOpacity";
    PenOpacity.propertyValue = 1;
    PenOpacity.updateType = Update|OrdinaryAttributes;
    PenOpacity.propertyType = QrealPropertyType;
    PenOpacity.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updatePenOpacity;
    m_PropertyInfoMap.insert("PenOpacity",PenOpacity);
    m_PropertyInfoMap[PenOpacity.propertyName].setConnect();

    GY_PropertyInfo LineStyle(this);
    LineStyle.propertyName = "LineStyle";
    LineStyle.propertyValue = QVariant();
    LineStyle.updateType = Update|OrdinaryAttributes;
    LineStyle.propertyType = LineStylePropertyType;
    LineStyle.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updateLineStyle;
    m_PropertyInfoMap.insert("LineStyle",LineStyle);
    m_PropertyInfoMap[LineStyle.propertyName].setConnect();

    GY_PropertyInfo IsVisible(this);
    IsVisible.propertyName = "IsVisible";
    IsVisible.propertyValue = true;
    IsVisible.updateType = Update|OrdinaryAttributes;
    IsVisible.propertyType = BoolPropertyType;
    IsVisible.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsRectWidthHeightItem::updateIsVisible;
    m_PropertyInfoMap.insert("IsVisible",IsVisible);
    m_PropertyInfoMap[IsVisible.propertyName].setConnect();
}
